///
/// @file WebKeyboardEvent.h
///
/// @brief The header for the WebKeyboardEvent class.
///
/// @author
///
/// This file is a part of Awesomium, a Web UI bridge for native apps.
///
/// Website: <http://www.awesomium.com>
///
/// Copyright (C) 2014 Awesomium Technologies LLC. All rights reserved.
/// Awesomium is a trademark of Awesomium Technologies LLC.
///
#ifndef AWESOMIUM_WEB_KEYBOARD_EVENT_H_
#define AWESOMIUM_WEB_KEYBOARD_EVENT_H_
#pragma once

#include <Awesomium/Platform.h>
#include <Awesomium/WebKeyboardCodes.h>
#if defined(_WIN32)
#include <Windows.h>
#endif

#if defined(__APPLE__)
#ifdef __OBJC__
@class NSEvent;
#else
class NSEvent;
#endif
#endif

namespace Awesomium {

///
/// @brief  A generic keyboard event that can be created from a
///         platform-specific event or synthesized from a virtual event.
///
/// @see  WebView::InjectKeyboardEvent
///
class OSM_EXPORT WebKeyboardEvent {
 public:
  ///
  /// Creates an empty WebKeyboardEvent, you will need to initialize its members
  /// yourself. This is useful for synthesizing your own keyboard events.
  ///
  WebKeyboardEvent();

#if defined(_WIN32)
  ///
  /// Creates a WebKeyboardEvent directly from a Windows keyboard event message.
  ///
  /// @note  Valid message types include:
  ///       - WM_KEYDOWN
  ///       - WM_KEYUP
  ///       - WM_SYSKEYDOWN
  ///       - WM_SYSKEYUP
  ///       - WM_CHAR
  ///       - WM_IMECHAR
  ///       - WM_SYSCHAR
  ///
  WebKeyboardEvent(UINT msg, WPARAM wparam, LPARAM lparam);

#elif defined(__APPLE__)
  ///
  /// Creates a WebKeyboardEvent directly from a Mac OSX NSEvent.
  ///
  WebKeyboardEvent(NSEvent* event);
#endif

  /// An enumeration of the different WebKeyboardEvent types.
  enum Type {
    /// Key-Down type
    kTypeKeyDown,

    /// Key-Up type
    kTypeKeyUp,

    /// Character input type
    kTypeChar,
  };

  /// An enumeration of the different keyboard modifiers.
  enum Modifiers {
    /// Whether or not a Shift key is down
    kModShiftKey     = 1 << 0,

    /// Whether or not a Control key is down
    kModControlKey   = 1 << 1,

    /// Whether or not an ALT key is down
    kModAltKey       = 1 << 2,

    /// Whether or not a meta key (Command-key on Mac, Windows-key on Win) is down
    kModMetaKey      = 1 << 3,

    /// Whether or not the key pressed is on the keypad
    kModIsKeypad     = 1 << 4,

    /// Whether or not the character input is the result of an auto-repeat timer.
    kModIsAutorepeat = 1 << 5,
  };

  /// The type of this WebKeyboardEvent
  Type type;

  ///
  /// The current state of the keyboard. Modifiers may be OR'd together to
  /// represent multiple values.
  ///
  int modifiers;

  ///
  /// The virtual key-code associated with this keyboard event. This is either
  /// directly from the event (ie, WPARAM on Windows) or via a mapping function.
  /// You can see a full list of the possible virtual key-codes in
  /// WebKeyboardCodes.h
  ///
  int virtual_key_code;

  ///
  /// The actual key-code generated by the platform. The DOM spec primarily
  /// uses Windows-equivalent codes (hence virtualKeyCode above) but it helps to
  /// also specify the platform-specific key-code as well.
  ///
  int native_key_code;

  ///
  /// This is a string identifying the key that was pressed. This can be
  /// generated from the virtual_key_code via the GetKeyIdentifierFromVirtualKeyCode()
  /// utility function. You can find the full list of key identifiers at:
  ///   http://www.w3.org/TR/DOM-Level-3-Events/keyset.html
  ///
  char key_identifier[20];

  ///
  /// The actual text generated by this keyboard event. This is usually only a
  /// single character but we're generous and cap it at a max of 4 characters.
  ///
  wchar16 text[4];

  ///
  /// The text generated by this keyboard event before all modifiers except
  /// shift are applied. This is used internally for working out shortcut keys.
  /// This is usually only a single character but we're generous and cap it at a
  /// max of 4 characters.
  ///
  wchar16 unmodified_text[4];

  ///
  /// Whether or not the pressed key is a "system key". This is a Windows-only
  /// concept and should be "false" for all non-Windows platforms. For more
  /// information, see the following link:
  ///   http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx
  ///
  bool is_system_key;
};

///
/// Utility function for generating a key identifier string from a virtual
/// key-code.
///
/// @param  virtual_key_code  The virtual key-code to generate the key
///                           identifier from.
///
/// @param  key_identifier_result  The string to store the result in (must be at
///                                least 20 chars).
///
void OSM_EXPORT GetKeyIdentifierFromVirtualKeyCode(int virtual_key_code,
  char** key_identifier_result);
}

#endif  // AWESOMIUM_WEB_KEYBOARD_EVENT_H_
